//Copyright (C) 2010 Ron Coleman. Contact: ronncoleman@gmail.com
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 3 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this library; if not, write to the Free Software
//Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

/*
 * EditUserDialog2.java
 *
 * Created on Dec 25, 2010, 10:01:47 PM
 */

package org.workplicity.cia.ui;

import java.awt.event.ItemEvent;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.DefaultListModel;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.workplicity.cia.util.CIAHelper;
import org.workplicity.cia.worklet.ElogsWorklet;
import org.workplicity.elog.entry.ElogUser;
import org.workplicity.elog.entry.ElogUser.Function;
import org.workplicity.elog.entry.Trade;
import org.workplicity.elog.repos.Elogs;
import org.workplicity.entry.User;
import org.workplicity.task.NetTask;
import org.workplicity.util.Helper;
import org.workplicity.worklet.WorkletContext;

/**
 * This class is a dialog for updating (or creating new) users.
 * If the auser id == -1, it creates a new auser; otherwise, it
 * updates the auser.
 * @author Ron Coleman
 */
public class EditUserDialog2 extends javax.swing.JDialog {
    private static int MIN_LOGNAME = 3;
    private static int MIN_PASSWORD = 3;
    private static String INVALIDS = " !_@#$%&*[](){}:;\"\'<>?/~.,`";
    private static String NON_STARTERS = "_0123456789";

    private WorkletContext context = ElogsWorklet.getInstance().getContext();

    private ElogUser user = null;

    private ArrayList<User> dirtyUsers = new ArrayList<User>( );
    
    /**
     * Constructor
     * @param parent Dialog
     * @param auser User to create or edit
     */
    public EditUserDialog2(JDialog parent, ElogUser user) {
        super(parent, true);
        initComponents();

        this.user = user;

        String logname = user.getId() == -1 ? "" : " ("+user.getLogname()+") ";
        String action = user.getId() == -1 ? "Create" : "Update";

        this.setTitle("Netlog"+logname+">> Users >> "+ action);

	this.setLocationRelativeTo(parent);

        initUser();
    }

    /**
     * Initialize the users and work slates.
     */
    private void initUser() {
        // Initialize the users
        initTrades();

        // Initialize the updateSubordinates
        initSubordinates();

        // Set up the selectedFunction combo box
        this.functionComboBox.addItem(ElogUser.Function.WORKER);
        this.functionComboBox.addItem(ElogUser.Function.SUPERVISOR);
        this.functionComboBox.addItem(ElogUser.Function.MANAGER);

        // Initialize the remaining fields
        this.lognTextField.setText(user.getLogname());
        this.passwTextField.setText(user.getPassword());
        this.firstTextField.setText(user.getFirstName());
        this.lastTextField.setText(user.getLastName());
        this.emailTextField.setText(user.getEmail());
        this.phoneTextField.setText(user.getPhone());
        this.authExtCheckBox.setSelected(user.isExtAuth());
        this.functionComboBox.setSelectedItem(user.getFunction());
        this.signonEnabledCheckBox.setSelected(user.getSignonEnabled());

        if(user.getId() != -1)
            this.lognTextField.setEnabled(false);
        else
            this.lognTextField.setEnabled(true);

//        // Get the boss, if there is one
//        if(user.getBossId() != -1) {
//            // Search of the boss (note: index 0 is "NA")
//            for(int i=1; i < bossComboBox.getItemCount(); i++) {
//                int aBoss = ((User) (bossComboBox.getItemAt(i))).getId();
//                if(user.getBossId().equals(aBoss)) {
//                    bossComboBox.setSelectedIndex(i);
//                    break;
//                }
//            }
//        }
    }

    private void initSubordinates() {
        // Initialize users assigned and available lists
        ArrayList<User> users = ElogsWorklet.getInstance().getUsersCache().getCache();

        DefaultListModel availUsersModel = (DefaultListModel) availUsers.getModel();
        availUsersModel.clear();

        DefaultListModel assignedUsersModel = (DefaultListModel) assignedUsers.getModel();
        assignedUsersModel.clear();

        // Partition users into assigned and available.
        // Note: a user can be assigned to another user and
        // so the user is not available, ie, he/she is on neither
        // avail or assigned lists
        for (User auser : users) {
            // If the user is me, skip
            if(auser.getId().equals(user.getId()))
                continue;

            // If the user is already the boss, skip
            if(auser.getId().equals(user.getBossId()))
                continue;

            // If the user's boss is not assigned, add the user to
            // avail list, otherwise put the user on the assigned
            // list
            ElogUser euser = (ElogUser)auser;

            if(euser.getBossId() == -1)
                availUsersModel.addElement(auser);

            else if(euser.getBossId().equals(user.getId()))
                assignedUsersModel.addElement(auser);

        }
    }

    private void initTrades() {
        // Initialize users assigned and available lists
        ArrayList<Trade> trades = ElogsWorklet.getInstance().getTrades().getCache();

        DefaultListModel availTradesModel = (DefaultListModel) availTrades.getModel();
        availTradesModel.clear();

        DefaultListModel assignedTradesModel = (DefaultListModel) assignedTrades.getModel();
        assignedTradesModel.clear();

        for (Trade trade : trades) {
            boolean assigned = false;

            for (Integer assignedTrade : user.getTradeList()) {
                if(assignedTrade.equals(trade.getId())) {
                    assigned = true;

                    assignedTradesModel.addElement(trade);

                    break;
                }
            }
            if(!assigned)
                availTradesModel.addElement(trade);
        }
    }

    /**
     * Scrape the screen and copy the values into the user instance.
     */
    private void scrape() {
        String logn = lognTextField.getText();
        user.setLogname(logn);

        String passw = new String(passwTextField.getPassword());
        user.setPassword(passw);

        user.setFirstName(this.firstTextField.getText());
        user.setLastName(this.lastTextField.getText());
        user.setEmail(this.emailTextField.getText());
        user.setPhone(this.phoneTextField.getText());
        user.setFunction((Function) this.functionComboBox.getSelectedItem());
        user.setSignonEnabled(this.signonEnabledCheckBox.isSelected());

        setTradeSelects(user);
    }

    /**
     * Inserts the auser into the repository.
     * @return True if successful, false otherwise
     */
    private boolean insertUser() {
        // Create an elog for the auser
        User me = Helper.whoAmI(context);

        if (me != null) {
            if(user.getId() == -1) {
                user.setCreateUserId(me.getId());

                boolean successful = insertElogRepos(user);

                if(!successful) {
                    JOptionPane.showMessageDialog(this, "NetLog repository creation failed.",
                        "NetLog", JOptionPane.ERROR_MESSAGE);
                    return false;
                }
            }
            else
                user.setUpdateUserId(me.getId());
        }

        if (this.authExtCheckBox.isSelected()) {
            user.setExtAuth(true);
        } else {
            user.setExtAuth(false);
        }

        boolean successful = Helper.insert(user, NetTask.REPOS_ACCOUNTS, context);

        if (!successful) {
            JOptionPane.showMessageDialog(this, "User save failed.",
                    "Netlog", JOptionPane.ERROR_MESSAGE);
            return false;
        }



        JOptionPane.showMessageDialog(this, "User '" + user.getLogname() + "' (id=" + user.getId() + ") saved successfully.",
                "Netlog", JOptionPane.INFORMATION_MESSAGE);

        return successful;
    }

    /**
     * This method updates the dirty users who have
     * gotten or gotten rid of the boss.
     * @return True of the updates were successful.
     */
    private boolean updateSubordinates() {
        DefaultListModel availModel = (DefaultListModel) this.availUsers.getModel();

        DefaultListModel assignedModel = (DefaultListModel) this.assignedUsers.getModel();

        for(User auser : dirtyUsers) {
            ElogUser euser = (ElogUser)auser;

            if(availModel.contains(auser))
                euser.setBossId(-1);

            else if(assignedModel.contains(auser))
                euser.setBossId(user.getId());

            // If user is dirty, user must be on the avail or assigned
            // list and so this case should never happen!
            else {
                JOptionPane.showMessageDialog(this, "Now that's embarrasing, an internal error!",
                        "Netlog", JOptionPane.ERROR_MESSAGE);

                return false;
            }

            if(!Helper.insert(auser, NetTask.REPOS_ACCOUNTS,context)) {
                JOptionPane.showMessageDialog(this, "Update of subordinate '"+auser+"' failed.",
                        "Netlog", JOptionPane.ERROR_MESSAGE);
                return false;
            }
        }

        return true;
    }

    /**
     * Inserts a new elog for the auser with a logname
     * @param logn Logname of the auser
     * @return True if the insert succeeded, false otherwise
     */
    private boolean insertElogRepos(ElogUser uwer) {
        BigInteger postfix = new BigInteger(32,new Random());

        String name = user.getLogname() + "-" + postfix.toString(32).toUpperCase();

        ElogUser me = (ElogUser) Helper.whoAmI(context);

        Elogs elogs = new Elogs(name);

        elogs.init(user);

        elogs.setCreateUserId(me.getId());

        elogs.setResident(false);

        boolean successful = Helper.insert(elogs, context);

        // If the log was successfully inserted point the auser
        // to that log -- the auser will be updated later
        if(successful) {
            user.setReposTitle(name);
            user.setElogId(elogs.getId());
        }

        return successful;
    }

    /**
     * Transfers users and workslates to the auser.
     * @param auser User
     */
    private void setTradeSelects(ElogUser user) {
        DefaultListModel model = (DefaultListModel) this.assignedTrades.getModel();

        user.getTradeList().clear();

        for(int i=0; i < model.getSize(); i++) {
            Trade trade = (Trade) model.elementAt(i);

            user.getTradeList().add(trade.getId());
        }
    }

    /**
     * Validates the user
     * @return True if user is valid, false otherwise.
     */
    private boolean validUser() {
        boolean valid = true;
        String msg = "Invalid logname or password.";
        try {
            // Check lexicographic validity
            String logname = user.getLogname();
            String passw = user.getPassword();

            if (logname.length() < MIN_LOGNAME || passw.length() < MIN_PASSWORD) {
                return valid = false;
            }

            if (logname.contains(INVALIDS) || passw.contains(INVALIDS)) {
                return valid = false;
            }

            if (logname.substring(0, 1).contains(NON_STARTERS)) {
                return valid = false;
            }

            // Check for duplicate
            ArrayList<User> users = ElogsWorklet.getInstance().getUsersCache().getCache();

            for (User auser : users) {
                if (auser.getId().equals(user.getId())) {
                    continue;
                }

                if (auser.getLogname().equals(logname)) {
                    msg = "Logname already exists.";
                    return valid = false;
                }
            }
        } catch (Exception e) {
        } finally {
            if (!valid)
                JOptionPane.showMessageDialog(this, msg,
                        "Netlog", JOptionPane.ERROR_MESSAGE);
        }

        return valid;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        lognTextField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        passwTextField = new javax.swing.JPasswordField();
        firstTextField = new javax.swing.JTextField();
        lastTextField = new javax.swing.JTextField();
        phoneTextField = new javax.swing.JTextField();
        emailTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        signonEnabledCheckBox = new javax.swing.JCheckBox();
        authExtCheckBox = new javax.swing.JCheckBox();
        jPanel2 = new javax.swing.JPanel();
        jLabel11 = new javax.swing.JLabel();
        assignUserButton = new javax.swing.JButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        availUsers = new javax.swing.JList();
        jLabel12 = new javax.swing.JLabel();
        unassignUserButton = new javax.swing.JButton();
        jScrollPane4 = new javax.swing.JScrollPane();
        assignedUsers = new javax.swing.JList();
        jLabel10 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        addTradeButton = new javax.swing.JButton();
        removeTradeButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        availTrades = new javax.swing.JList();
        jScrollPane2 = new javax.swing.JScrollPane();
        assignedTrades = new javax.swing.JList();
        cancelButton = new javax.swing.JButton();
        saveButton = new javax.swing.JButton();
        jLabel7 = new javax.swing.JLabel();
        functionComboBox = new javax.swing.JComboBox();
        jCheckBox1 = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jTabbedPane1.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel1.setText("Logname:");

        lognTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel2.setText("Password:");

        passwTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        firstTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        lastTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        phoneTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        emailTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        jLabel4.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel4.setText("First:");

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel3.setText("Phone:");

        jLabel5.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel5.setText("Last:");

        jLabel6.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel6.setText("Email:");

        signonEnabledCheckBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        signonEnabledCheckBox.setSelected(true);
        signonEnabledCheckBox.setText("Sign-on enabled");

        authExtCheckBox.setFont(new java.awt.Font("Tahoma", 0, 12));
        authExtCheckBox.setText("Authenticate externally");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(authExtCheckBox, javax.swing.GroupLayout.DEFAULT_SIZE, 408, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(signonEnabledCheckBox)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(jLabel3)
                                    .addComponent(jLabel1)
                                    .addComponent(jLabel4))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(phoneTextField)
                                    .addComponent(firstTextField)
                                    .addComponent(lognTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(jLabel2)
                                    .addComponent(jLabel5)
                                    .addComponent(jLabel6))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(passwTextField)
                                    .addComponent(emailTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)
                                    .addComponent(lastTextField))))
                        .addContainerGap())))
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {lognTextField, passwTextField});

        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2)
                    .addComponent(lognTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(passwTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(firstTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4)
                    .addComponent(lastTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(phoneTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6)
                    .addComponent(emailTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(signonEnabledCheckBox)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(authExtCheckBox)
                .addContainerGap(35, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Personal", jPanel1);

        jLabel11.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel11.setText("Assign");

        assignUserButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/right2.PNG"))); // NOI18N
        assignUserButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                assignUserButtonActionPerformed(evt);
            }
        });

        availUsers.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        availUsers.setModel(new DefaultListModel());
        jScrollPane3.setViewportView(availUsers);

        jLabel12.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel12.setText("Unassign");

        unassignUserButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/left2.PNG"))); // NOI18N
        unassignUserButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unassignUserButtonActionPerformed(evt);
            }
        });

        assignedUsers.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        assignedUsers.setModel(new DefaultListModel());
        jScrollPane4.setViewportView(assignedUsers);

        jLabel10.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        jLabel13.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel13.setText("To this user:");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addGap(42, 42, 42)
                                .addComponent(jLabel11)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(assignUserButton, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(30, 30, 30)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addComponent(unassignUserButton, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel12))
                            .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 121, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(jLabel10)
                    .addComponent(jLabel13))
                .addContainerGap(136, Short.MAX_VALUE))
        );

        jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jScrollPane3, jScrollPane4});

        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jLabel10)
                        .addGap(18, 18, 18)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(unassignUserButton)
                            .addComponent(assignUserButton)
                            .addComponent(jLabel11)
                            .addComponent(jLabel12)))
                    .addComponent(jLabel13))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Reporting", jPanel2);

        jLabel8.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel8.setText("Assign");

        jLabel9.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel9.setText("Unassign");

        addTradeButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        addTradeButton.setIcon(new javax.swing.ImageIcon("C:\\Documents and Settings\\Ron\\Workplicity\\CIAElog\\src\\right2.PNG")); // NOI18N
        addTradeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addTradeButtonActionPerformed(evt);
            }
        });

        removeTradeButton.setIcon(new javax.swing.ImageIcon("C:\\Documents and Settings\\Ron\\Workplicity\\CIAElog\\src\\left2.PNG")); // NOI18N
        removeTradeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeTradeButtonActionPerformed(evt);
            }
        });

        availTrades.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        availTrades.setModel(new DefaultListModel());
        jScrollPane1.setViewportView(availTrades);

        assignedTrades.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        assignedTrades.setModel(new DefaultListModel( ));
        jScrollPane2.setViewportView(assignedTrades);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGap(57, 57, 57)
                        .addComponent(jLabel8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(addTradeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(32, 32, 32)
                        .addComponent(removeTradeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel9))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(32, 32, 32)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(118, Short.MAX_VALUE))
        );

        jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jScrollPane1, jScrollPane2});

        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGap(16, 16, 16)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel9)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel3Layout.createSequentialGroup()
                            .addGap(11, 11, 11)
                            .addComponent(jLabel8))
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(removeTradeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(1, 1, 1))
                            .addComponent(addTradeButton, javax.swing.GroupLayout.Alignment.TRAILING))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Trades", jPanel3);

        cancelButton.setFont(new java.awt.Font("Tahoma", 0, 12));
        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        saveButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        saveButton.setText("Save");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel7.setText("Type:");

        functionComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        functionComboBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                functionComboBoxItemStateChanged(evt);
            }
        });
        functionComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                functionComboBoxActionPerformed(evt);
            }
        });

        jCheckBox1.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jCheckBox1.setText("Admin enabled");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(293, Short.MAX_VALUE)
                .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cancelButton)
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 423, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel7)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(functionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 144, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jCheckBox1)
                .addContainerGap(140, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(11, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(functionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7)
                    .addComponent(jCheckBox1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 216, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(saveButton))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Removes a auser from the auser.
     * @param evt Event
     */
    private void removeTradeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeTradeButtonActionPerformed
        // Transfer assigned users to the available ones
        int[] deleteIndices = this.assignedTrades.getSelectedIndices();

        DefaultListModel destModel = (DefaultListModel) this.availTrades.getModel();

        DefaultListModel srcModel = (DefaultListModel) this.assignedTrades.getModel();

        ArrayList<Trade> tradeGarbage = new ArrayList<Trade>();

        for(int i=0; i < deleteIndices.length; i++) {
            Trade trade = (Trade) srcModel.getElementAt(deleteIndices[i]);

            if(destModel.contains(trade))
                continue;

            destModel.addElement(trade);

            tradeGarbage.add(trade);
        }

        for(Trade trade : tradeGarbage)
            srcModel.removeElement(trade);
}//GEN-LAST:event_removeTradeButtonActionPerformed

    /**
     * Adds a auser to the auser.
     * @param evt Event
     */
    private void addTradeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTradeButtonActionPerformed
        // Transfers available users to assigned ones
        int[] addIndices = this.availTrades.getSelectedIndices();

        DefaultListModel srcModel = (DefaultListModel) this.availTrades.getModel();

        DefaultListModel destModel = (DefaultListModel) this.assignedTrades.getModel();

        ArrayList<Trade> serviceGarbage = new ArrayList<Trade>();

        for(int i=0; i < addIndices.length; i++) {
            Trade trade = (Trade) srcModel.getElementAt(addIndices[i]);

            if(destModel.contains(trade))
                continue;

            destModel.addElement(trade);

            serviceGarbage.add(trade);
        }

        for(Trade trade : serviceGarbage)
            srcModel.removeElement(trade);
}//GEN-LAST:event_addTradeButtonActionPerformed

    private void functionComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_functionComboBoxActionPerformed
        // TODO add your handling code here:
}//GEN-LAST:event_functionComboBoxActionPerformed

    private void functionComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_functionComboBoxItemStateChanged
        // Combo boxes send two events: one for the deselected item
        // and one for the selected one -- we only want the selected one
        if(evt.getStateChange() == ItemEvent.DESELECTED)
            return;
}//GEN-LAST:event_functionComboBoxItemStateChanged

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        final JDialog dialog = this;

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    // Scrape the screen
                    scrape();

                    // Check if user has valid logname, etc.
                    if (!validUser())
                        return;

                    // Check that for valid reporting of subordinates
                    if (!validReporting())
                        return;

                    // Insert the user
                    if (!insertUser())
                        return;

                    // Update subordinates for dirty users
                    if (!updateSubordinates())
                        return;

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    dialog.dispose();
                }
            }
        });
    }//GEN-LAST:event_saveButtonActionPerformed

    /**
     * Validates the inputs.
     * @return True if the user configuration is validReporting.
     */
    private boolean validReporting() {
        // Check if user has subordinates but the user
        // user not in the management function
        if(CIAHelper.isManagement(user) || dirtyUsers.isEmpty())
            return true;

        DefaultListModel assignedModel = (DefaultListModel) this.assignedUsers.getModel();

        User subordinate = null;
        for(User auser : dirtyUsers) {
            if(!assignedModel.contains(auser))
                continue;

            subordinate = auser;
            break;
        }

        if(subordinate == null)
            return true;

        String msg = "Non-management user assigned subordinate(s).";
        msg += "\nProceed?";

        int n = JOptionPane.showConfirmDialog(
                this,
                msg,
                "Confirm",
                JOptionPane.YES_NO_OPTION);

        if (n == 1) {
            return false;
        }

        return true;
    }

    private void assignUserButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_assignUserButtonActionPerformed
       // Transfers available user to assigned ones
        int[] addIndices = this.availUsers.getSelectedIndices();

        DefaultListModel srcModel = (DefaultListModel) this.availUsers.getModel();

        DefaultListModel destModel = (DefaultListModel) this.assignedUsers.getModel();

        ArrayList<User> userGarbage = new ArrayList<User>();

        for(int i=0; i < addIndices.length; i++) {
            User auser = (User) srcModel.getElementAt(addIndices[i]);

            if(destModel.contains(auser))
                continue;

            destModel.addElement(auser);

            if(!dirtyUsers.contains(auser))
                dirtyUsers.add(auser);

            userGarbage.add(auser);
        }

        for(User auser : userGarbage)
            srcModel.removeElement(auser);
    }//GEN-LAST:event_assignUserButtonActionPerformed

    private void unassignUserButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unassignUserButtonActionPerformed
        // Transfer assigned user to the available ones
        int[] deleteIndices = this.assignedUsers.getSelectedIndices();

        DefaultListModel destModel = (DefaultListModel) this.availUsers.getModel();

        DefaultListModel srcModel = (DefaultListModel) this.assignedUsers.getModel();

        ArrayList<User> userGarbage = new ArrayList<User>();

        for(int i=0; i < deleteIndices.length; i++) {
            User auser = (User) srcModel.getElementAt(deleteIndices[i]);

            if(destModel.contains(auser))
                continue;

            destModel.addElement(auser);

            if(!dirtyUsers.contains(auser))
                dirtyUsers.add(auser);

            userGarbage.add(auser);
        }

        for(User auser : userGarbage)
            srcModel.removeElement(auser);
    }//GEN-LAST:event_unassignUserButtonActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                EditUserDialog2 dialog = new EditUserDialog2(new javax.swing.JDialog(),null);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addTradeButton;
    private javax.swing.JButton assignUserButton;
    private javax.swing.JList assignedTrades;
    private javax.swing.JList assignedUsers;
    private javax.swing.JCheckBox authExtCheckBox;
    private javax.swing.JList availTrades;
    private javax.swing.JList availUsers;
    private javax.swing.JButton cancelButton;
    private javax.swing.JTextField emailTextField;
    private javax.swing.JTextField firstTextField;
    private javax.swing.JComboBox functionComboBox;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTextField lastTextField;
    private javax.swing.JTextField lognTextField;
    private javax.swing.JPasswordField passwTextField;
    private javax.swing.JTextField phoneTextField;
    private javax.swing.JButton removeTradeButton;
    private javax.swing.JButton saveButton;
    private javax.swing.JCheckBox signonEnabledCheckBox;
    private javax.swing.JButton unassignUserButton;
    // End of variables declaration//GEN-END:variables

}
